package system

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
	systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
)

type SysPrescriptionRecordService struct{}

// CreateSysPrescriptionRecord 创建药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) CreateSysPrescriptionRecord(ctx context.Context, sysPrescriptionRecord *system.SysPrescriptionRecord) (err error) {
	err = global.GVA_DB.Create(sysPrescriptionRecord).Error
	return err
}

// DeleteSysPrescriptionRecord 删除药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) DeleteSysPrescriptionRecord(ctx context.Context, ID string) (err error) {
	err = global.GVA_DB.Delete(&system.SysPrescriptionRecord{}, "id = ?", ID).Error
	return err
}

// DeleteSysPrescriptionRecordByIds 批量删除药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) DeleteSysPrescriptionRecordByIds(ctx context.Context, IDs []string) (err error) {
	err = global.GVA_DB.Delete(&[]system.SysPrescriptionRecord{}, "id in ?", IDs).Error
	return err
}

// UpdateSysPrescriptionRecord 更新药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) UpdateSysPrescriptionRecord(ctx context.Context, sysPrescriptionRecord system.SysPrescriptionRecord) (err error) {
	err = global.GVA_DB.Model(&system.SysPrescriptionRecord{}).Where("id = ?", sysPrescriptionRecord.ID).Updates(&sysPrescriptionRecord).Error
	return err
}

// GetSysPrescriptionRecord 根据ID获取药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) GetSysPrescriptionRecord(ctx context.Context, ID string) (sysPrescriptionRecord system.SysPrescriptionRecord, err error) {
	err = global.GVA_DB.Where("id = ?", ID).First(&sysPrescriptionRecord).Error
	return
}

// GetSysPrescriptionRecordInfoList 分页获取药方记录
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) GetSysPrescriptionRecordInfoList(ctx context.Context, info systemReq.SysPrescriptionRecordSearch) (list []system.SysPrescriptionRecord, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&system.SysPrescriptionRecord{})
	var sysPrescriptionRecords []system.SysPrescriptionRecord
	// 如果有条件搜索 下方会自动创建搜索语句
	if len(info.CreatedAtRange) == 2 {
		db = db.Where("created_at BETWEEN ? AND ?", info.CreatedAtRange[0], info.CreatedAtRange[1])
	}
	if info.PatientId > 0 {
		db = db.Where("patient_id = ?", info.PatientId)
	}

	err = db.Count(&total).Error
	if err != nil {
		return
	}

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}

	err = db.Find(&sysPrescriptionRecords).Error
	return sysPrescriptionRecords, total, err
}
func (sysPrescriptionRecordService *SysPrescriptionRecordService) GetSysPrescriptionRecordPublic(ctx context.Context) {
	// 此方法为获取数据源定义的数据
	// 请自行实现
}

// CheckStock 核准库存
// Author [yourname](https://github.com/yourname)
func (sysPrescriptionRecordService *SysPrescriptionRecordService) CheckStock(ctx context.Context, ID int64) (err error) {

	// 开启事务
	tx := global.GVA_DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
			panic(r)
		}
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	//查询ID的处方
	var sysPrescriptionRecord system.SysPrescriptionRecord
	err = tx.Model(&system.SysPrescriptionRecord{}).Where("id = ?", ID).First(&sysPrescriptionRecord).Error
	if err != nil {
		return
	}

	ji := *sysPrescriptionRecord.Ji

	// 检查处方状态，防止重复核准
	if sysPrescriptionRecord.Status != nil && *sysPrescriptionRecord.Status == "approved" {
		return fmt.Errorf("处方已核准，不能重复操作")
	}

	//取出prescription_data
	prescriptionData := sysPrescriptionRecord.PrescriptionData
	fmt.Println("prescriptionData", prescriptionData)
	//遍历prescription_data，拿到sys_drugs的id后扣除库存

	// 解析prescription_data为数组
	var prescriptionDataArray []system.PrescriptionItem

	// 将datatypes.JSON转换为字符串再解析
	prescriptionDataStr := string(prescriptionData)
	fmt.Println("prescriptionDataStr", prescriptionDataStr)

	// 先解析为字符串（处理双重编码）
	var jsonStr string
	err = json.Unmarshal([]byte(prescriptionDataStr), &jsonStr)
	if err != nil {
		// 如果解析失败，说明不是双重编码，直接使用原字符串
		jsonStr = prescriptionDataStr
	}
	fmt.Println("jsonStr", jsonStr)

	// 再解析为数组
	err = json.Unmarshal([]byte(jsonStr), &prescriptionDataArray)
	fmt.Println("prescriptionDataArray", prescriptionDataArray)
	if err != nil {
		return fmt.Errorf("解析处方数据失败: %v", err)
	}

	// 先检查所有药品库存是否充足
	for _, item := range prescriptionDataArray {
		drugID := item.ID

		grams := item.Grams

		var sysDrugs system.SysDrugs
		err = tx.Model(&system.SysDrugs{}).Where("id = ?", drugID).First(&sysDrugs).Error
		if err != nil {
			return fmt.Errorf("查询药品失败: %v", err)
		}

		if sysDrugs.Stock == nil || *sysDrugs.Stock < grams {
			return fmt.Errorf("药品 %s 库存不足，当前库存: %d，需要: %d", item.Name,
				func() int {
					if sysDrugs.Stock == nil {
						return 0
					} else {
						return *sysDrugs.Stock
					}
				}(), grams)
		}
	}

	// 扣减库存
	for _, item := range prescriptionDataArray {
		drugID := item.ID
		grams := item.Grams * ji

		var sysDrugs system.SysDrugs
		err = tx.Model(&system.SysDrugs{}).Where("id = ?", drugID).First(&sysDrugs).Error
		if err != nil {
			return fmt.Errorf("查询药品失败: %v", err)
		}

		// 扣减库存
		*sysDrugs.Stock -= grams
		err = tx.Save(&sysDrugs).Error
		if err != nil {
			return fmt.Errorf("更新药品库存失败: %v", err)
		}
	}

	// 更新处方记录状态为已核准
	approvedStatus := "approved"
	sysPrescriptionRecord.Status = &approvedStatus
	err = tx.Save(&sysPrescriptionRecord).Error
	if err != nil {
		return fmt.Errorf("更新处方状态失败: %v", err)
	}

	return nil
}
